package com.situ.stl.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.situ.stl.constants.Constants;
import com.situ.stl.entity.Course;
import com.situ.stl.entity.Member;
import com.situ.stl.entity.Reserve;
import com.situ.stl.mapper.CourseMapper;
import com.situ.stl.mapper.MemberMapper;
import com.situ.stl.mapper.ReserveMapper;
import com.situ.stl.service.ReserveService;
import com.situ.stl.util.Result;
import com.situ.stl.vo.ReserveVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
@Service
public class ReserveServiceImpl implements ReserveService {
    @Autowired
    private ReserveMapper reserveMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private MemberMapper memberMapper;

    @Override
    public List<Reserve> select(Reserve reserve) {
        return reserveMapper.select(reserve);
    }

    @Override
    public PageInfo searchByPage(Integer page, Integer limit, Reserve reserve) {
        if (ObjectUtils.isEmpty(page)) page = 1;
        if (ObjectUtils.isEmpty(limit)) limit = 10;
        // 开启分页查询
        PageHelper.startPage(page, limit);
        List<Reserve> reserves = reserveMapper.select(reserve);
        PageInfo<Reserve> pageInfo = new PageInfo<>(reserves);
        return pageInfo;
    }


    @Override
    public List<ReserveVo> getReservationsByMemberId1(Integer memberId) {
        return reserveMapper.selectByMemberId1(memberId);
    }

    @Override
    public int modifyReserve5(Reserve reserve) throws Exception {
        // 验证参数
        if (reserve.getCourseId() == null || reserve.getMemberId() == null || reserve.getScore() == null) {
            throw new Exception("参数不完整");
        }

        // 验证评分范围
        if (reserve.getScore() < 1 || reserve.getScore() > 5) {
            throw new Exception("评分必须在1-5分之间");
        }

        // 获取课程信息
        Course course = courseMapper.selectCourseById(reserve.getCourseId());
        if (ObjectUtils.isEmpty(course)) {
            throw new Exception("课程不存在，无法评分！");
        }

        // 获取会员的预约记录
        Reserve dbReserve = reserveMapper.selectByMemberIdAndCourseId(reserve);
        if (ObjectUtils.isEmpty(dbReserve)) {
            throw new Exception("您没有预约过该课程，无法评分！");
        }

        // 检查是否已完成课程
        Date nowDate = new Date();
        if (nowDate.getTime() <= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
            throw new Exception("只能在下课后评分！");
        }


        // 更新评分

        dbReserve.setScore((reserve.getScore() + dbReserve.getScore()) / 2);
        return reserveMapper.modify(dbReserve);
    }

    @Override
    public Reserve searchByCourseIdAndMemberId(Integer id, Integer memberId) {
        return reserveMapper.searchByCidAndMid(id, memberId);
    }

    @Override
    public int modifyReserve4(Reserve reserve) throws Exception {

        //课程是否存在
        Course course = courseMapper.selectCourseById(reserve.getCourseId());
        if (ObjectUtils.isEmpty(course)) {
            throw new Exception("课程不存在，无法预约！");
        }
        //会员是否存在
        Member member = memberMapper.selectMemberById(reserve.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new Exception("会员不存在，无法预约！");
        }
//只能在开课前1小时预约
        Date nowDate = new Date();


        if (reserve.getStatus() == 2) {
            if (nowDate.getTime() < course.getTime().getTime()) {
                throw new Exception("只能在课程中签到");
            }
            if (nowDate.getTime() >= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
                throw new Exception("您已迟到，请下次准时参加");
            }
            // 检查余额是否足够
            if (member.getBalance() < course.getMoney()) {
                throw new Exception("余额不足，无法签到");
            }

            // 扣钱并更新会员信息
            member.setBalance(member.getBalance() - course.getMoney());
            int memberUpdated = memberMapper.modifyMember(member);
            if (memberUpdated <= 0) {
                throw new Exception("扣款失败，请重试");
            }

            reserve.setIsqd(true);

            return reserveMapper.modify(reserve);
        }
        if (reserve.getStatus() == 3) {
            if (nowDate.getTime() <= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
                throw new Exception("只能在下课后未到");
            }
        }
        if (reserve.getStatus() == 1) {
            reserve.setStatus(0);
          return reserveMapper.modify(reserve);
        }
        if (reserve.getStatus() == 0) {
            reserve.setStatus(1);
            return reserveMapper.modify(reserve);
        }

        return 1;
    }


    @Override
    public int modifyReserve(Reserve reserve) throws Exception {


        if (reserve.getStatus() == 0 || reserve.getStatus() == 3 || reserve.getStatus() == 2) {
            throw new Exception("已取消或已完课或正在上课的预约无法编辑");
        }

        // 根据课程id和会员id，查看是否预约过
        Reserve dbReserve = reserveMapper.selectByMemberIdAndCourseId(reserve);
        if (!ObjectUtils.isEmpty(dbReserve) && reserve.getStatus() != 0) {
            throw new Exception("该预约信息已经存在，无法重复预约！");
        }

        //课程是否存在
        Course course = courseMapper.selectCourseById(reserve.getCourseId());
        if (ObjectUtils.isEmpty(course)) {
            throw new Exception("课程不存在，无法预约！");
        }
        //会员是否存在
        Member member = memberMapper.selectMemberById(reserve.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new Exception("会员不存在，无法预约！");
        }
//只能在开课前1小时预约
        Date nowDate = new Date();
        if (reserve.getStatus() != 2 && reserve.getStatus() != 3) {
            if (course.getTime().getTime() - nowDate.getTime() > 60 * 60 * 1000) {
                throw new Exception("只能在开课一小时前预约！");
            }
            //课程已经开始，不能预约
            if (nowDate.getTime() > course.getTime().getTime() && nowDate.getTime() <= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
                throw new Exception("已经开始上课了");
            }
            //课程结束，无法预约
            if (nowDate.getTime() > course.getTime().getTime() && nowDate.getTime() >= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
                throw new Exception("课程已经结束");
            }
        }


        reserve.setReserveTime(nowDate);
        return reserveMapper.modify(reserve);
    }


    @Override
    public int addReserve(Reserve reserve) throws Exception {
        //根据课程id和会员id，查看是否预约过,并且状态为0或1或2
        Reserve dbReserve = reserveMapper.selectByMemberIdAndCourseId(reserve);
        // 如果存在已取消的预约记录，则更新它
        if (!ObjectUtils.isEmpty(dbReserve) && dbReserve.getStatus() == 0) {
            reserve.setStatus(1);
            reserve.setId(dbReserve.getId());
            return reserveMapper.modify(reserve);
        }
        // 如果存在预约记录且状态不是已取消(0)，则抛出异常
        if (!ObjectUtils.isEmpty(dbReserve)) {
            throw new Exception("该预约信息已经存在，无法重复预约！");
        }

        //课程是否存在
        Course course = courseMapper.selectCourseById(reserve.getCourseId());
        if (ObjectUtils.isEmpty(course)) {
            throw new Exception("课程不存在，无法预约！");
        }
        //会员是否存在
        Member member = memberMapper.selectMemberById(reserve.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new Exception("会员不存在，无法预约！");
        }
        //同一个会员的预约的课程时间范围内，不能预约其他课程
        List<Reserve> memberReserves = reserveMapper.selectByMemberId(reserve.getMemberId());
        Course newCourse = courseMapper.selectCourseById(reserve.getCourseId());
        long newCourseTime = newCourse.getTime().getTime();
        long newCourseEnd = newCourseTime + newCourse.getLength() * 60 * 1000;
        for (Reserve existingReserve : memberReserves) {
            if (existingReserve.getStatus() == 0 || existingReserve.getStatus() == 3) continue; // 跳过已取消的预约

            Course existingCourse = courseMapper.selectCourseById(existingReserve.getCourseId());
            long existingCourseTime = existingCourse.getTime().getTime();
            long existingCourseEnd = existingCourseTime + existingCourse.getLength() * 60 * 1000;

            // 检查时间是否重叠
            if (!(newCourseEnd <= existingCourseTime || newCourseTime >= existingCourseEnd)) {
                throw new Exception("同一个会员的预约的课程时间范围内，不能预约其他课程");
            }
        }
        //只能在开课前1小时预约
        Date nowDate = new Date();

        if (course.getTime().getTime() - nowDate.getTime() > 60 * 60 * 1000) {
            throw new Exception("只能在开课一小时前预约！");
        }
        //课程已经开始，不能预约

        if (nowDate.getTime() > course.getTime().getTime() && nowDate.getTime() <= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
            throw new Exception("已经开始上课了");
        }
        //课程结束，无法预约
        if (nowDate.getTime() > course.getTime().getTime() && nowDate.getTime() >= course.getTime().getTime() + (course.getLength() * 60 * 1000)) {
            throw new Exception("课程已经结束");
        }

        reserve.setStatus(1);
        reserve.setScore(5.0);
        reserve.setReserveTime(nowDate);
        return reserveMapper.insert(reserve);
    }

    @Override
    public int modifyReserve1(Reserve reserve) {
        return reserveMapper.modify(reserve);
    }

    @Override
    public int modifyReserve2(Reserve reserve) {
        return reserveMapper.modify(reserve);
    }

    @Override

    @Transactional
    public int batchReserve(List<Reserve> reserves) throws Exception {
        if (reserves.isEmpty()) {
            throw new Exception("请至少选择一条预约！");
        }

        // 验证所有预约记录是否属于同一课程
        Integer courseId = reserves.get(0).getCourseId();
        for (Reserve reserve : reserves) {
            if (!reserve.getCourseId().equals(courseId)) {
                throw new Exception("不属于同一课程");
            }
        }

        // 获取课程信息用于验证
        Course course = courseMapper.selectCourseById(courseId);
        if (course == null) {
            throw new Exception("课程不存在");
        }



        Date now = new Date();
        Date courseEnd = new Date(course.getTime().getTime() + course.getLength() * 60 * 1000);
        Date courseStart = course.getTime();
        // 获取批量操作的状态（所有预约记录的状态应该相同）
        Integer status = reserves.get(0).getStatus();

        // 根据不同的状态进行验证和处理
        for (Reserve reserve : reserves) {
            // 签到操作验证
            if (status == 2) {
                if (now.before(course.getTime()) || now.after(courseEnd)) {
                    throw new Exception("只能在课程进行中签到");
                }
                Member member = memberMapper.selectMemberById(reserve.getMemberId());
                // 检查余额是否足够
                if (member.getBalance() < course.getMoney()) {
                    throw new Exception("余额不足，无法签到");
                }

                // 扣钱并更新会员信息
                member.setBalance(member.getBalance() - course.getMoney());
                int memberUpdated = memberMapper.modifyMember(member);
                if (memberUpdated <= 0) {
                    throw new Exception("扣款失败，请重试");
                }
                reserve.setIsqd(true);
            }
            // 未到操作验证
            else if (status == 3) {
                if (reserve.getIsqd() == true){
                    throw new Exception("已签到的会员不能未到");
                }
                if (now.before(courseEnd)) {
                    throw new Exception("只能在下课后标记未到");
                }
                reserve.setIsqd(false);
            }
            // 取消预约操作
            else if (status == 0) {
                if (now.after(courseStart)) {
                    throw new Exception("课程已开始，无法取消预约");
                }
                reserve.setStatus(0);
            }
            // 重新预约操作
            else if (status == 1) {
                if (now.after(courseStart)) {
                    throw new Exception("课程已开始，无法重新预约");
                }
                // 检查是否已经预约过（非取消状态）
                Reserve existingReserve = reserveMapper.selectByMemberIdAndCourseId(reserve);
                if (existingReserve != null && existingReserve.getStatus() != 0) {
                    throw new Exception("该会员已有有效预约，不能重复预约");
                }
                reserve.setStatus(1);
            }
        }
        int count = 0;
        for (Reserve reserve : reserves) {
            count += reserveMapper.modify(reserve);
        }
        return count;
        // 执行批量更新

    }
}
